Обработчики обновления информационной базы
Область применения: управляемое приложение, обычное приложение.
Действует для конфигураций на базе Библиотеки стандартных подсистем.
Содержит уточнения к требованиям других стандартов.
См. документацию к подсистеме "Обновление версии ИБ" на ИТС.
1. Основные сведения о библиотеке (основной конфигурации)
2. Расположение обработчиков обновления
3. Реализация обработчиков обновления
4. Переход на новые версии библиотек
1. Основные сведения о библиотеке (основной конфигурации)
1.1. При разработке конфигураций на базе библиотек, каждая библиотека должна сообщить о себе ряд сведений, необходимых для корректного обновления информационной базы на новую версию конфигурации:
- Имя
- Версию
- Список обработчиков обновления
- Зависимости от других библиотек.
Эти сведения размещаются в специальном общем модуле библиотеки, имя которого должно начинаться с ОбновлениеИнформационнойБазы…
Пример:
В конфигурации УТ 11 модуль обработчиков обновления называется ОбновлениеИнформационнойБазыУТ
Имена модулей всех используемых в конфигурации библиотек следует явно перечислить в общем модуле ПодсистемыКонфигурацииПереопределяемый в виде:
Процедура ПриДобавленииПодсистем(МодулиПодсистем) Экспорт
МодулиПодсистем.Добавить("ОбновлениеИнформационнойБазыУТ");
КонецПроцедуры
Кроме того, аналогичный модуль также должен быть определен и для основной конфигурации.
При создании общего модуля ОбновлениеИнформационнойБазы… следует использовать шаблон:
////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы <библиотеки или конфигурации>.
//
/////////////////////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс
////////////////////////////////////////////////////////////////////////////////
// Получение сведений о библиотеке (или конфигурации).
// Заполняет основные сведения о библиотеке или основной конфигурации.
// Библиотека, имя которой имя совпадает с именем конфигурации в метаданных, определяется как основная конфигурация.
//
// Параметры:
// Описание - Структура - сведения о библиотеке:
//
// Имя - Строка - имя библиотеки, например, "СтандартныеПодсистемы".
// Версия - Строка - версия в формате из 4-х цифр, например, "2.1.3.1".
//
// ТребуемыеПодсистемы - Массив - имена других библиотек (Строка), от которых зависит данная библиотека.
// Обработчики обновления таких библотек должны быть вызваны ранее
// обработчиков обновления данной библиотеки.
// При циклических зависимостях или, напротив, отсутствии каких-либо зависимостей,
// порядок вызова обработчиков обновления определяется порядком добавления модулей
// в процедуре ПриДобавленииПодсистем общего модуля ПодсистемыКонфигурацииПереопределяемый.
// РежимВыполненияОтложенныхОбработчиков - Строка - "Последовательно" - отложенные обработчики обновления выполняются
// последовательно в интервале от номера версии информационной базы до номера
// версии конфигурации включительно или "Параллельно" - отложенный обработчик после
// обработки первой порции данных передает управление следующему обработчику, а после
// выполнения последнего обработчика цикл повторяется заново.
//
Процедура ПриДобавленииПодсистемы(Описание) Экспорт
Описание.Имя = "<Имя библиотеки>";
Описание.Версия = "XX.XX.XX.XX";
Описание.ТребуемыеПодсистемы.Добавить("СтандартныеПодсистемы");
Описание.РежимВыполненияОтложенныхОбработчиков = "Последовательно";
КонецПроцедуры
////////////////////////////////////////////////////////////////////////////////
// Обработчики обновления информационной базы.
// Добавляет в список процедуры-обработчики обновления данных ИБ
// для всех поддерживаемых версий библиотеки или конфигурации.
// Вызывается перед началом обновления данных ИБ для построения плана обновления.
//
// Параметры:
// Обработчики - ТаблицаЗначений - описание полей
// см. в процедуре ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления
//
// Пример добавления процедуры-обработчика в список:
// Обработчик = Обработчики.Добавить();
// Обработчик.Версия = "1.0.0.0";
// Обработчик.Процедура = "ОбновлениеИБ.ПерейтиНаВерсию_1_0_0_0";
// Обработчик.РежимВыполнения = "Монопольно";
//
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
// Обработчики, выполняемые при каждом обновлении ИБ
// Обработчики, выполняемые при переходе на определенную версию
// Обработчики, выполняемые при заполнении пустой ИБ
КонецПроцедуры
// Вызывается перед процедурами-обработчиками обновления данных ИБ.
//
Процедура ПередОбновлениемИнформационнойБазы() Экспорт
КонецПроцедуры
// Вызывается после завершения обновления данных ИБ.
//
// Параметры:
// ПредыдущаяВерсия - Строка - версия до обновления. "0.0.0.0" для "пустой" ИБ.
// ТекущаяВерсия - Строка - версия после обновления.
// ВыполненныеОбработчики - ДеревоЗначений - список выполненных процедур-обработчиков обновления,
// сгруппированных по номеру версии.
// ВыводитьОписаниеОбновлений - Булево - (возвращаемое значение) если установить Истина,
// то будет вывена форма с описанием обновлений. По умолчанию, Истина.
// МонопольныйРежим - Булево - Истина, если обновление выполнялось в монопольном режиме.
//
Процедура ПослеОбновленияИнформационнойБазы(Знач ПредыдущаяВерсия, Знач ТекущаяВерсия,
Знач ВыполненныеОбработчики, ВыводитьОписаниеОбновлений, МонопольныйРежим) Экспорт
КонецПроцедуры
// Вызывается при подготовке табличного документа с описанием изменений в программе.
//
// Параметры:
// Макет - ТабличныйДокумент - описание обновления всех библиотек и конфигурации.
// Макет можно дополнить или заменить.
// См. также общий макет ОписаниеИзмененийСистемы.
//
Процедура ПриПодготовкеМакетаОписанияОбновлений(Знач Макет) Экспорт
КонецПроцедуры
// Позволяет переопределить режим обновления данных информационной базы.
// Для использования в редких (нештатных) случаях перехода, не предусмотренных в
// стандартной процедуре определения режима обновления.
//
// Параметры:
// РежимОбновленияДанных - Строка - в обработчике можно присвоить одно из значений:
// "НачальноеЗаполнение" - если это первый запуск пустой базы (области данных);
// "ОбновлениеВерсии" - если выполняется первый запуск после обновление конфигурации базы данных;
// "ПереходСДругойПрограммы" - если выполняется первый запуск после обновление конфигурации базы данных,
// в которой изменилось имя основной конфигурации.
//
// СтандартнаяОбработка - Булево - если присвоить Ложь, то стандартная процедура
// определения режима обновления не выполняется,
// а используется значение РежимОбновленияДанных.
//
Процедура ПриОпределенииРежимаОбновленияДанных(РежимОбновленияДанных, СтандартнаяОбработка) Экспорт
КонецПроцедуры
// Добавляет в список процедуры-обработчики перехода с другой программы (с другим именем конфигурации).
// Например, для перехода между разными, но родственными конфигурациями: базовая -> проф -> корп.
// Вызывается перед началом обновления данных ИБ.
//
// Параметры:
// Обработчики - ТаблицаЗначений - с колонками:
// * ПредыдущееИмяКонфигурации - Строка - имя конфигурации, с которой выполняется переход;
// или "*", если нужно выполнять при переходе с любой конфигурации.
// * Процедура - Строка - полное имя процедуры-обработчика перехода с программы ПредыдущееИмяКонфигурации.
// Например, "ОбновлениеИнформационнойБазыУПП.ЗаполнитьУчетнуюПолитику"
// Обязательно должна быть экспортной.
//
// Пример добавления процедуры-обработчика в список:
// Обработчик = Обработчики.Добавить();
// Обработчик.ПредыдущееИмяКонфигурации = "УправлениеТорговлей";
// Обработчик.Процедура = "ОбновлениеИнформационнойБазыУПП.ЗаполнитьУчетнуюПолитику";
//
Процедура ПриДобавленииОбработчиковПереходаСДругойПрограммы(Обработчики) Экспорт
КонецПроцедуры
// Вызывается после выполнения всех процедур-обработчиков перехода с другой программы (с другим именем конфигурации),
// и до начала выполнения обновления данных ИБ.
//
// Параметры:
// ПредыдущееИмяКонфигурации - Строка - имя конфигурации до перехода.
// ПредыдущаяВерсияКонфигурации - Строка - имя предыдущей конфигурации (до перехода).
// Параметры - Структура -
// * ВыполнитьОбновлениеСВерсии - Булево - по умолчанию Истина. Если установить Ложь,
// то будут выполнена только обязательные обработчики обновления (с версией "*").
// * ВерсияКонфигурации - Строка - номер версии после перехода.
// По умолчанию, равен значению версии конфигурации в свойствах метаданных.
// Для того чтобы выполнить, например, все обработчики обновления с версии ПредыдущаяВерсияКонфигурации,
// следует установить значение параметра в ПредыдущаяВерсияКонфигурации.
// Для того чтобы выполнить вообще все обработчики обновления, установить значение "0.0.0.1".
// * ОчиститьСведенияОПредыдущейКонфигурации - Булево - по умолчанию Истина.
// Для случаев когда предыдущая конфигурация совпадает по имени с подсистемой текущей конфигурации, следует указать Ложь.
//
Процедура ПриЗавершенииПереходаСДругойПрограммы(Знач ПредыдущееИмяКонфигурации,
Знач ПредыдущаяВерсияКонфигурации, Параметры) Экспорт
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
////////////////////////////////////////////////////////////////////////////////
// Заполнение пустой ИБ
////////////////////////////////////////////////////////////////////////////////
// Обновление ИБ
#КонецОбласти
1.2. Обработчики обновления данных информационной базы предназначены для дополнительной обработки данных после завершения обновления конфигурации (реструктуризации) базы данных:
- инициализация новых констант, новых реквизитов, реквизитов новых предопределенных элементов;
- перенос данных из устаревших структур метаданных в новые;
- генерация новых данных
- и т.п.
Для автогенерируемых строк, которые программно записываются в информационную базу, например при заполнении наименований предопределенных элементов справочников, ПВХ и т.п., следует руководствоваться стандартом Автогенерированные данные в информационной базе: требования по локализации.
1.3. Обработчик обновления данных информационной базы состоит из двух частей:
-
описательной - сообщает, когда должен выполниться обработчик, и где он находится в конфигурации;
-
программной - непосредственно код модификации данных ИБ, оформленный в виде процедуры-обработчика обновления.
Добавление описаний новых обработчиков выполняется в процедуре ПриДобавленииОбработчиковОбновления с помощью вставки фрагмента кода по шаблону:
Обработчик = Обработчики.Добавить();
Обработчик.Версия = "<номер версии>";
Обработчик.Процедура = "<полное имя экспортной процедуры>";
Обработчик.НачальноеЗаполнение = {Истина|Ложь};
Обработчик.РежимВыполнения = {"Монопольно"|"Оперативно"|"Отложенно"};
Данный код добавляет новую строку в таблицу значений Обработчики, строка которой имеет следующие поля:
Версия (Строка) – номер версии конфигурации, при обновлении на которую должна быть вызвана процедура обновления, указанная в параметре Процедура.
-
Номер версии конфигурации указывается в формате «Р.П.В.С» (Р – старший номер редакции; П – младший номер редакции; В – номер версии; С – номер сборки. Если следующую версию нельзя определить, то можно указать следующий номер сборки.
-
Если в качестве версии указан символ «*», то обработчик обновления должен выполняться каждый раз при обновлении информационной базы, независимо от номера версии конфигурации. Обработчики такого вида предназначены для обновления служебных, системных данных (например, обновление поставляемых профилей и групп доступа).
-
Если свойство Версия не задано, то должно быть установлено в Истина свойство НачальноеЗаполнение (см. далее).
Процедура (Строка) – идентификатор процедуры, содержащий полный путь к процедуре-обработчику обновления.
Например, "Справочник.Валюты.ЗаполнитьКодДляПоиска".
НачальноеЗаполнение (Булево) – если Истина, то обработчик будет вызван при первом запуске пустой информационной базы (версия «0.0.0.0»), созданной из файла поставки конфигурации и не содержащей данных.
Это обработчики первоначального заполнения базы.
РежимВыполнения (Строка) – принимает одно из значений: "Монопольно", "Оперативно" и "Отложенно". Если свойство не задано, то по умолчанию обработчик – монопольный.
- Монопольно – если обработчик обновления необходимо выполнять монопольно, в условиях отсутствия активных сеансов работы пользователей, регламентных заданий, внешних соединений и подключений по веб-сервисам. В противном случае, обновление версии программы прерывается. Подробнее см. Ограничения на использование монопольного режима обработчиков обновления
Монопольные обработчики предназначены для обновления тех данных, обработка которых должна быть обязательно завершена к моменту входа пользователей в программу. Для сокращения времени простоя (ожидания обработки данных), рекомендуется большие объемы данных обновлять отложенно (см. ниже).
Примеры монопольных обработчиков: обработка небольшого объема данных текущего периода, активных позиций номенклатуры и т.п.
Если хотя бы один обработчик обновления конфигурации – монопольный, то все оперативные обработчики (см. далее) выполняются в монопольном режиме.
В случае если обработчик обновления – обязательный (свойство Версия = «*»), то значение Монопольно следует устанавливать только в тех случаях, когда обработчик обновления должен программно определить, требуется ли монопольный режим для его выполнения:- Такой обработчик вызывается дважды, в него передается параметр Параметры типа Структура, в котором имеется свойство МонопольныйРежим (Булево)
- При первом вызове в режиме проверки, свойство МонопольныйРежим содержит значение Ложь.
- Код обработчика не должен модифицировать данные ИБ
- Если в ходе выполнения обработчика возникает необходимость внесения изменений в ИБ, обработчик должен установить значение свойства в Истина и прекратить свое выполнение
- При втором вызове в режиме выполнения свойство МонопольныйРежим содержит значение Истина
- Код обработчик может модифицировать данные ИБ
- Изменение значения свойства в этом случае игнорируется
- Оперативно – если обработчик обновления необходимо выполнять не монопольно: при активных сеансах работы пользователей, регламентных заданий, внешних соединений и подключений через веб-сервисы.
Оперативные обработчики следует применять в редких случаях, когда важно сократить время ожидания пользователей при переходе на исправительные релизы, которые не содержат изменений в структуре данных, и обновление на которые должно выполняться динамически.
Подробнее см. Оперативное обновление данных.
- Отложенно – если обработчик обновления необходимо выполнять в фоне после того, как завершено выполнение монопольных (оперативных) обработчиков, и пользователям уже разрешен вход в программу.
Отложенные обработчики предназначены для обработки той части данных ИБ, которые не препятствуют пользователям начинать свою работу с новой версией программы, не дожидаясь завершения обработки этих данных.
Примеры отложенных обработчиков: обработка больших архивов данных за закрытые/прошлые периоды, неактивных позиций номенклатуры, различных данных, отключенных в данный момент функциональными опциями и т.п.
Подробнее см. Отложенное обновление данных.
Если в конфигурации (библиотеке) используется параллельный режим отложенного обновления (в процедуре ПриДобавленииПодсистемы свойство РежимВыполненияОтложенныхОбработчиков = "Параллельно"), то для написания отложенных обработчиков следует руководствоваться стандартом Параллельный режим отложенного обновления.
Пример описания обработчика, для выполнения которого требуется монопольный режим:
Обработчик = Обработчики.Добавить();
Обработчик.РежимВыполнения = "Монопольно";
Обработчик.Версия = "11.1.0.0";
Обработчик.Процедура = "Справочник.МойСправочник.ЗаполнитьКодДляПоиска";
Пример реализации обработчика в модуле менеджера Справочник.МойСправочник:
// Обработчик обновления УТ 11.1.0.0
//
// Перебираются все элементы справочника, в которых не заполнен код для поиска,
// и заполняется кодом справочника без лидирующих нулей и префиксов
//
Процедура ЗаполнитьКодДляПоиска() Экспорт
...
2. Расположение обработчиков обновления
2.1. Процедура-обработчик должна оформляться в виде экспортной процедуры.
Располагать процедуру следует в модуле менеджера того объекта метаданных, обновление которого она выполняет.
Пример:
Если в справочник «Подразделения» добавили новый реквизит, который необходимо заполнить значением по умолчанию, то процедура-обработчик должна располагаться в модуле менеджера этого справочника.
2.2. В некоторых случаях, когда невозможно соотнести обработчик с каким-то конкретным объектом метаданных, допустимо расположение процедуры-обработчика в серверном общем модуле, назначение которого по смыслу связано с выполняемой обработкой ИБ (например, процедуры обновления, связанные со складской функциональностью должны располагаться в общем модуле СкладСервер). При этом процедура должна располагаться в служебной части модуля, в подразделе «Обновление ИБ».
3. Реализация обработчиков обновления
3.1. К процедуре-обработчику предъявляются следующие требования:
-
Обработчик не должен содержать логики по интерактивному взаимодействию с пользователем.
-
Алгоритм обработчика должен быть построен так, чтобы не прерывать, не зацикливать обработку данных, не оставлять необработанные данные и не требовать каких-либо дополнительных действий от пользователя для продолжения обработки данных. Любое невыполнение обработчика следует рассматривать как логическую ошибку и перепроектировать логику обработчика. Например, если номер документа, который создается в обработчике, оказывается неуникальным, то присваивать новый незанятый номер, а не завершать работу обработчика вызовом исключения. Если обрабатываемые обработчиком данные ссылаются на несуществующие данные (т.н. "битая ссылка"), то пропускать обработку этих данных или выполнять с недостающими значениями по умолчанию.
- В параллельных отложенных обработчиках не следует вызывать исключение, которое приведет к остановке всей процедуры обновления. В остальных видах обработчиков допустимо вызывать исключение только в случае критической ошибки при обновлении, когда исчерпаны все другие возможности обхода проблемы. Остановка обновления информационной базы приведет к невозможности запуска до тех пор, пока причины ошибки не будут устранены.
-
Обработчик должен быть рассчитан на неоднократное выполнение. На одних и тех же данных результат выполнения обработчика должен быть идентичен при любом количестве вызовов этого обработчика (например, повторный запуск обработчика не должен приводить к дублированию данных в информационной базе).
- В пределах одной версии (значение свойства Версия), работоспособность обработчика не должна ставиться в зависимость от очередности его выполнения. Если подобные зависимости проявляются, то такие обработчики необходимо объединять в один.
- Если в конфигурации предусмотрены планы обмена РИБ с отборами, то также нужно учитывать, что в обновляемом подчиненном узле РИБ могут быть неполные данные: например, в нем имеются движения по регистру, а сам регистратор отсутствует. При этом обработчик обновления должен пропускать обновление таких данных.
3.2. Обработчик обновления не должен содержать лишних, избыточных действий с данными – должен выполняться максимально быстро.
3.2.1. Для этого необходимо отключать бизнес-логику при обработке данных. В большинстве случаев, с помощью установки признака ОбменДанными.Загрузка:
ДокументОбъект.ОбменДанными.Загрузка = Истина;
В отдельных случаях, для частичного отключения бизнес-логики допустимо предусмотреть дополнительный признак, например:
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтключитьМоюБизнесЛогику");
3.2.2. Для большинства обрабатываемых данных следует отключать регистрацию изменений на узлах планов обмена, чтобы избежать отправки всего объема обработанных данных во все узлы. Таким образом:
- В распределенной информационной базе (РИБ) обработка данных должна выполняться независимо в каждом из узлов;
- При обмене между произвольными конфигурациями (программами) обработка данных не должна приводить к их выгрузке в базы-получатели.
Исключение составляют случаи создания ссылочных объектов, которые должны быть перенесены механизмами обмена данными в другие узлы РИБ с тем же значением реквизита Ссылка.
3.2.3. Таким образом, в коде обработчика обновления вместо
ДокументОбъект.Записать();
должно быть:
ДокументОбъект.ОбменДанными.Загрузка = Истина; // отключить всю бизнес-логику при записи
ДокументОбъект.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
ДокументОбъект.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
ДокументОбъект.Записать();
При использовании в конфигурации Библиотеки стандартных подсистем (БСП) версии 2.1.4 и выше следует использовать процедуру ЗаписатьДанные общего модуля ОбновлениеИнформационнойБазы:
ОбновлениеИнформационнойБазы.ЗаписатьДанные(ДокументОбъект);
3.3. Перед процедурой-обработчиком должен быть комментарий. При этом первая строка комментария должна содержать информацию о версии конфигурации, для которой предназначен этот обработчик. Последующие строки комментария должны содержать ответ на следующие вопросы:
-
Какие данные будут изменены (что меняем)?
-
Какие изменения будут внесены в эти данные (как меняем)?
Пример:
// Обработчик обновления УТ 11.1.0.0
//
// Перебираются все элементы справочника, в которых не заполнен код для поиска,
// и заполняется кодом справочника без лидирующих нулей и префиксов
//
Процедура ЗаполнитьКодДляПоиска() Экспорт
4. Переход на новые версии библиотек
4.1. При постановке конфигурации на поддержку к новой версии библиотеки, следует увеличивать номер версии конфигурации. Это необходимо для запуска обработчиков обновления информационной базы.